using Commons.Models.Locks;
using Commons.Models.Settings.Dtos.Locks;
using System;
using System.Collections.Generic;
using Commons.Models.Settings.Parsers;

namespace Commons.Models.Settings.Mappers.Locks
{
	public class LockMapper : UnlockConditionsMapper, IMapper<LockDto, Lock>
	{
		protected static Dictionary<int, Lock> missingIdRef = new Dictionary<int, Lock>();
		
		public LockMapper ()
			: base()
		{
		}
		
		public Lock Map (LockDto config)
		{
			if (config == null)
			{
				return null;
			}
			
			Lock lockObject = null;
			ISettingsModel settingsModel = ParserContextHolder.Context.SettingsModel;
			LockSettings lockSetting = settingsModel.GetSettings<LockSettings>();
			
			if (config.IdRef > 0)
			{
				if (lockSetting.HasLock(config.IdRef))
					return lockSetting.GetLock(config.IdRef);
				
				if (missingIdRef.ContainsKey(config.IdRef))
					return missingIdRef[config.IdRef];
				
				lockObject = new Lock(config.IdRef);
				missingIdRef.Add(config.IdRef, lockObject);
				return lockObject;
			}
			
			if (lockSetting.HasLock(config.Id))
				throw new Exception("Duplicated Lock with id="+config.Id.ToString());
				
			if (missingIdRef.ContainsKey(config.Id))
			{
				ParseLock(config, missingIdRef[config.Id]);
				lockObject = missingIdRef[config.Id];
			}
			else 
			{
				lockObject = new Lock(config.Id);
				ParseLock(config, lockObject);
			}
			return lockObject;	
		}
		
		protected void ParseLock (LockDto config, Lock lockObject)
		{
			ISettingsModel settingsModel = ParserContextHolder.Context.SettingsModel;
			LockSettings lockSettings = settingsModel.GetSettings<LockSettings>();
			
			List<IUnlockConditionDto> allUnlockConditionDto = config.GetAllUnlockConditionDto();
			if (allUnlockConditionDto.Count > 0)
			{
				foreach (IUnlockConditionDto dto in allUnlockConditionDto)
				{
					lockObject.AddUnlockCondition(CreateUnlockCondition(dto));	
				}
			}
			
			lockSettings.AddLock(lockObject);
		}
	}
}

